package com.loklok.code.confuse.util;

import com.intellij.psi.PsiType;
import com.intellij.psi.impl.source.PsiClassReferenceType;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class GenericTypeResolver {



    private static final Set<Class<?>> WRAPPER_TYPES = new HashSet<>();

    static {
        WRAPPER_TYPES.add(Boolean.class);
        WRAPPER_TYPES.add(Character.class);
        WRAPPER_TYPES.add(Byte.class);
        WRAPPER_TYPES.add(Short.class);
        WRAPPER_TYPES.add(Integer.class);
        WRAPPER_TYPES.add(Long.class);
        WRAPPER_TYPES.add(Float.class);
        WRAPPER_TYPES.add(Double.class);
        WRAPPER_TYPES.add(Void.class);
        WRAPPER_TYPES.add(String.class);
    }

    /**
     * 判断给定的类是否为基础类型的包装类或 Void 类型
     *
     * @param className 全限定类名，例如 "java.lang.Integer"
     * @return 是否为包装类或 Void
     */
    public static boolean isWrapperOrVoid(String className) {
        try {
            Class<?> clazz = Class.forName(className);
            return WRAPPER_TYPES.contains(clazz) || className.startsWith("java.");
        } catch (ClassNotFoundException e) {
            // 类未找到，返回 false 或根据需要处理异常
            return false;
        }
    }

    /**
     * 重载方法，接受 Class 对象作为参数
     */
    public static boolean isWrapperOrVoid(Class<?> clazz) {
        return WRAPPER_TYPES.contains(clazz);
    }



    public static ResolvedTypeInfo resolveNestedGeneric(PsiType returnType) {
        List<String> allGenerics = new ArrayList<>();
        String baseType = resolveNested(returnType, allGenerics);
        return new ResolvedTypeInfo(baseType, allGenerics);
    }

    private static String resolveNested(PsiType type, List<String> result) {
        if (!(type instanceof PsiClassReferenceType)) {
            result.add(type.getCanonicalText());
            return type.getPresentableText();
        }

        PsiClassReferenceType refType = (PsiClassReferenceType) type;
        result.add(refType.getCanonicalText());

        for (PsiType param : refType.getParameters()) {
            resolveNested(param, result);
        }

        return refType.getClassName();
    }

    public static class ResolvedTypeInfo {
        private final String baseType;
        private final List<String> genericTypes;

        public ResolvedTypeInfo(String baseType, List<String> genericTypes) {
            this.baseType = baseType;
            this.genericTypes = genericTypes;
        }

        public String getBaseType() {
            return baseType;
        }

        public List<String> getGenericTypes() {
            return genericTypes;
        }

        @Override
        public String toString() {
            if (genericTypes.isEmpty()) {
                return baseType;
            }
            return baseType + "<" + String.join(", ", genericTypes) + ">";
        }
    }
}
